#encoding=utf-8
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response
from django.views.generic.edit import FormView
from django.views.generic.edit import CreateView
from django.template import RequestContext
from django.views.generic.base import RedirectView
from django.views import generic
from django.core.serializers.json import DjangoJSONEncoder

from .models import Ship, Ship_data, Engine_data, NewUser
from .forms import AddShipForm, SearchHistoryForm
from django.utils import timezone
from django_sse.views import BaseSseView 
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.utils.timezone import now
import decimal
import json
import time
import datetime

@method_decorator(login_required, name='dispatch')
class BoardEvents(BaseSseView):
    def iterator(self):
        while True:
            try:
                ship_id  = self.kwargs.get("ship_id")
                ship     = Ship.objects.get(ship_id=ship_id)
                engines  = ship.ship_about_engine.all()
                monitors = []
                datas    = []
                for engine in engines:
                    monitor_list = engine.engine_about_monitor.all()
                    monitors.append({'monitor_list_name':engine.inship_name, 'monitor_list':monitor_list})
                for monitor in monitors:
                    monitor_list = monitor['monitor_list']
                    for sub in monitor_list:
                        monitor_name = '%s:%s'%(sub.show_name, sub.engine_id)
                        monitor_data = sub.monitor_about_engine_data.order_by('-generation_data_time').values('speed', 'water_temperature',\
                            'oil_temperature')[0]
                        datas.append(json.dumps({'msg':'success', 'monitor_name':monitor_name, 'monitor_data':{'speed':\
                            decimal.Decimal(monitor_data['speed']), 'water_temperature':monitor_data['water_temperature'],\
                            'oil_temperature':monitor_data['oil_temperature']}},default=decimal_default))
                context = json.dumps(datas)
                self.sse.add_message("date", context)
                time.sleep(1)
                yield
            except Exception, e:
                datas = []
                msg = {'msg':e}
                datas.append(msg)
            finally:
                pass

class HistoryEvents(BaseSseView):
    def iterator(self):
        while True:
            try:
                ship_id  = self.kwargs.get("ship_id")
                ship     = Ship.objects.get(ship_id=ship_id)
                engines  = ship.ship_about_engine.all()
                monitors = []
                datas    = []
                for engine in engines:
                    monitor_list = engine.engine_about_monitor.all()
                    monitors.append({'monitor_list_name':engine.inship_name, 'monitor_list':monitor_list})
                for monitor in monitors:
                    monitor_list = monitor['monitor_list']
                    for sub in monitor_list:
                        monitor_name = '%s:%s'%(sub.show_name, sub.engine_id)
                        monitor_data = sub.monitor_about_engine_data.order_by('-generation_data_time').values('generation_data_time','speed', 'water_temperature',\
                            'oil_temperature')[0]
                        datas.append(json.dumps({'msg':'success', 'monitor_name':monitor_name, 'monitor_data':{'generation_data_time':monitor_data['generation_data_time'],'speed':\
                            decimal.Decimal(monitor_data['speed']), 'water_temperature':monitor_data['water_temperature'],\
                            'oil_temperature':monitor_data['oil_temperature']}},cls=DjangoJSONEncoder))
                context = json.dumps(datas)
                self.sse.add_message("date", context)
                time.sleep(1)
                yield
            except Exception, e:
                datas = []
                msg = {'msg':e}
                datas.append(msg)
            finally:
                pass

@method_decorator(login_required, name='dispatch')
class IndexView(generic.ListView):
    template_name       = 'map/index.html'
    context_object_name = 'latest_ship_list'

    def get_queryset(self, *args, **kwargs):
        """Return the last five published questions."""
        user = NewUser.objects.get(username=self.request.user.username)
        ships = user.user_about_ship.order_by('-ship_build_time')
        return ships

@method_decorator(login_required, name='dispatch')
class ShipListView(generic.ListView):
    """获取相应的船舶数据，以表格的形式渲染到前端"""
    model               = Ship
    template_name       = 'map/ship_list.html'
    context_object_name = "latest_ship_list"
    def get_queryset(self, *args, **kwargs):
        user = NewUser.objects.get(username=self.request.user.username)
        ship_objects = user.user_about_ship.order_by('-ship_build_time')
        if(ship_objects[0]):
            msg = 'have ship'
        else:
            msg = 'none ship'
        context = ship_objects
        return context

@method_decorator(login_required, name='dispatch')
class AddShipView(CreateView):
    template_name = 'map/form.html'
    form_class    = AddShipForm
    model         = Ship
    success_url   = 'updateship'

    def dispatch(self, *args, **kwargs):
        return super(AddShipView, self).dispatch(*args, **kwargs)

@method_decorator(login_required, name='dispatch')
class MonitorView(generic.DetailView):
    template_name       = 'map/data_charts.html'
    model               = Engine_data
    context_object_name = "engine_monitor"

    def get_object(self):
        try:
            ship_id  = self.kwargs.get("ship_id")
            ship     = Ship.objects.get(ship_id=ship_id)
            engines  = ship.ship_about_engine.all()
            monitors = []
            datas    = []
            for index,engine in enumerate(engines):
                engine_name  = engine.inship_name
                monitor_list = {'monitor_list_name': engine_name, 'monitor_list':engine.engine_about_monitor.all()}
                monitors.append(monitor_list)
            for monitor in monitors:
                monitor_list = monitor['monitor_list']
                for sub in monitor_list:
                    monitor_name = '%s:%s'%(sub.show_name, sub.engine_id)
                    monitor_data = sub.monitor_about_engine_data.order_by('-generation_data_time').values()[0]
                    data         = {'monitor_name':monitor_name, 'msg':'success','ship_id':ship_id, 'monitor_data':monitor_data}
                    datas.append(data)
            for index, data in enumerate(datas):
                datas[index]['monitor_data']['others'] = _data_analyse(data['monitor_data']['others'])
            return datas
        except Exception, e:
            ship_id = self.kwargs.get("ship_id")
            datas   = []
            data    = {'msg':'获取数据失败','ship_id':ship_id}
            datas.append(data);
            return datas
        finally:
            pass

@method_decorator(login_required, name='dispatch')    
class HistoryView(generic.DetailView):
    template_name       = 'map/history.html'
    model               = Engine_data
    context_object_name = 'history_data'

    def get_object(self):
        try:
            ship_id  = self.kwargs.get("ship_id")
            ship     = Ship.objects.get(ship_id=ship_id)
            engines  = ship.ship_about_engine.all()
            monitors = []
            datas    = []
            temp     = []
            for engine in engines:
                engine_name = engine.inship_name
                monitors.append({'monitor_list_name':engine_name, 'monitor_list':engine.engine_about_monitor.all()})
            for monitor in monitors:
                monitor_list = monitor['monitor_list']
                for sub in monitor_list:
                    monitor_name = '%s:%s'%(sub.show_name, sub.engine_id)
                    monitor_data = sub.monitor_about_engine_data.order_by('-generation_data_time').values('generation_data_time','speed', 'water_temperature',\
                        'oil_temperature')[:50]
                    # for index,data in enumerate(monitor_data):
                    #     temp.append(json.dumps({'generation_data_time':data['generation_data_time'], 'speed':decimal.Decimal(data['speed']),\
                    #      'water_temperature':data['water_temperature'], 'oil_temperature':data['oil_temperature']}, cls=DjangoJSONEncoder))
                    # end_data = json.dumps(temp)
                    datas.append({'monitor_name':monitor_name, 'msg':'success', 'ship_id':ship_id, 'monitor_data':monitor_data})
            return datas
        except Exception, e:
            ship_id = self.kwargs.get("ship_id")
            datas   = []
            data    = {'msg':'获取数据失败','ship_id':ship_id}
            datas.append(data);
            return datas
        finally:
            pass

@method_decorator(login_required, name='dispatch')
class AddShipRedirectView(RedirectView):
    permanent    = False
    query_string = True
    pattern_name = 'addship-success'

    def save_data(request):
        pass
    def get_redirect_url(self, *args, **kwargs):
        # ship = get_object_or_404(Ship, pk=kwargs['pk'])
        return super(AddShipRedirectView, self).get_redirect_url(*args, **kwargs)

def decimal_default(obj):
    if isinstance(obj, decimal.Decimal):
        return float(obj)
    raise TypeError

@login_required
def get_ship_location(request, ship_id):
    ship    = Ship_data.objects.filter(ship_id=ship_id).order_by('-generation_data_time').values('longitude', 'latitude', 'altitude')
    context = json.dumps({'longitude':decimal.Decimal(ship[0]['longitude']), 'latitude':decimal.Decimal(ship[0]['latitude']), 'altitude':decimal.Decimal(ship[0]['altitude'])},
                                                                                    default=decimal_default)
    return HttpResponse(context)

@login_required
def get_ship_history_line(request,ship_id):
    try:
        ship                 = Ship.objects.get(ship_id=ship_id)
        history_line         = ship.ship_about_ship_data.order_by('-generation_data_time').values('longitude', 'latitude', 'altitude')[:50]
        history_line_context = []
        msg                  = json.dumps({'msg':'历史轨迹获取成功'})
        history_line_context.append(msg)
        # import pdb
        # pdb.set_trace()
        for point in history_line:
            context = json.dumps({'longitude':decimal.Decimal(point['longitude']), 'latitude':decimal.Decimal(point['latitude']), 'altitude':decimal.Decimal(point['altitude'])}, default=decimal_default)
            history_line_context.append(context)
        history_line_context = json.dumps(history_line_context)
        return HttpResponse(history_line_context)
    except Exception, e:
        msg = e
        return msg
    finally:
        pass

@login_required
def get_ship_detail(request, ship_id):
    data_ship   = {}
    detail_data = []
    try:
        detail_data = Ship.objects.filter(ship_id=ship_id).values()
        ship        = Ship.objects.get(ship_id=ship_id)
        data_ship   = ship.ship_about_ship_data.order_by('-generation_data_time').values()[0]
        if data_ship:
            data_ship = data_ship
        else:
            data_ship = {'longitude':0, 'latitude':0}
        msg = "success"
    except Exception, e:
        msg = e
    return render_to_response('map/detail.html',RequestContext(request,{'data_ship':data_ship,'detail_data':detail_data[0], 'msg':msg}))

def ship_detail_select_history(request, ship_id):
    form = SearchHistoryForm(request.GET)
    begintime_month = ''
    begintime_year  = ''
    begintime_day   = ''
    endtime_month   = ''
    endtime_year    = ''
    endtime_day     = ''
    if form.is_valid():
        begintime_month = request.GET['begintime_month']
        begintime_year  = request.GET['begintime_year']
        begintime_day   = request.GET['begintime_day']
        endtime_month   = request.GET['endtime_month']
        endtime_year    = request.GET['endtime_year']
        endtime_day     = request.GET['endtime_day'] 
    if begintime_month:
        user = NewUser.objects.get(username=request.user.username)
        ship_objects = user.user_about_ship.order_by('-ship_build_time')
        begintime_x = '-'.join([begintime_year, begintime_month, begintime_day])
        endtime_x   = '-'.join([endtime_year, endtime_month, endtime_day])
        begintime   = datetime.date(int(begintime_year), int(begintime_month), int(begintime_day))
        endtime     = datetime.date(int(endtime_year), int(endtime_month), int(endtime_day))
        ship        = Ship.objects.get(ship_id=ship_id)
        history_line         = ship.ship_about_ship_data.filter(generation_data_time__range=(begintime, endtime)).order_by('-generation_data_time').values('longitude', 'latitude', 'altitude')
        return render_to_response('map/index.html', RequestContext(request, {'history_line':history_line, 'latest_ship_list':ship_objects}))
    else:
        return render_to_response('map/_detail_select_history.html', RequestContext(request,{'form':form, 'ship_id':ship_id}))

def _data_analyse(data):
    result  = data.split('|')
    context = {}
    n       = 0
    for i in range(len(result)//2):
        key          = result[n]
        value        = result[n+1]
        n            = n+2
        context[key] = value
    return context

def select(request, ship_id, select):
    ISOTIMEFORMAT='%Y-%m-%d %X'
    date_to = datetime.datetime.now()
    if select == 'oneyear':
        date_from = date_to - datetime.timedelta(days=365)
    elif select == 'onemonth':
        date_from = date_to - datetime.timedelta(days=30)
    else:
        date_from = date_to - datetime.timedelta(days=1)
    try:
        ship_id  = ship_id
        ship     = Ship.objects.get(ship_id=ship_id)
        engines  = ship.ship_about_engine.all()
        monitors = []
        datas    = []
        for engine in engines:
            engine_name = engine.inship_name
            monitors.append({'monitor_list_name':engine_name, 'monitor_list':engine.engine_about_monitor.all()})
        for monitor in monitors:
            temp     = []
            monitor_list = monitor['monitor_list']
            for sub in monitor_list:
                monitor_name = '%s:%s'%(sub.show_name, sub.engine_id)
                monitor_data = sub.monitor_about_engine_data.filter(generation_data_time__range=(date_from, date_to)).order_by('-generation_data_time').values('generation_data_time','speed', 'water_temperature',\
                    'oil_temperature')
                for index,data in enumerate(monitor_data):
                    temp.append(json.dumps({'generation_data_time':data['generation_data_time'], 'speed':decimal.Decimal(data['speed']),\
                     'water_temperature':data['water_temperature'], 'oil_temperature':data['oil_temperature']}, cls=DjangoJSONEncoder))
                end_data = json.dumps(temp)
                datas.append({'monitor_name':monitor_name, 'msg':'success', 'ship_id':ship_id, 'monitor_data':end_data})
        return HttpResponse(json.dumps(datas))
    except Exception, e:
        ship_id = self.kwargs.get("ship_id")
        datas   = []
        data    = {'msg':'获取数据失败','ship_id':ship_id}
        datas.append(data);
        return datas
    finally:
        pass





